import sys
import os
from datetime import datetime
from PyQt5.QtWidgets import (QApplication, QMainWindow, QHBoxLayout, QWidget, QPushButton, QFileDialog,
                             QTableWidget, QTableWidgetItem, QLabel, QDialog, QVBoxLayout, QMessageBox, QHeaderView,
                             QTextEdit)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
import qdarkstyle
from PyQt5.QtGui import QColor, QBrush
from PyQt5.QtWidgets import QStyledItemDelegate
import mimetypes


class ColorDelegate(QStyledItemDelegate):
    def paint(self, painter, option, index):
        if index.column() == 1:  # 文件类型列
            if index.data() == '文件夹':
                option.backgroundBrush = QBrush(QColor(230, 230, 250))  # 淡紫色
            else:
                option.backgroundBrush = QBrush(QColor(240, 248, 255))  # 淡蓝色
        super().paint(painter, option, index)

class FileViewer(QMainWindow):
    def __init__(self):
        super().__init__()
        self.current_folder = None
        self.folder_stack = []
        self.initUI()

    def initUI(self):
        self.setWindowTitle('文件查看器')
        self.setGeometry(100, 100, 800, 600)

        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        main_layout = QVBoxLayout(central_widget)

        button_layout = QHBoxLayout()

        self.button_back = QPushButton('回退', self)
        self.button_back.clicked.connect(self.go_back)
        self.button_back.setEnabled(False)
        button_layout.addWidget(self.button_back)

        self.button_select_folder = QPushButton('选择文件夹', self)
        self.button_select_folder.clicked.connect(self.select_folder)
        button_layout.addWidget(self.button_select_folder)

        main_layout.addLayout(button_layout)

        self.table_widget = QTableWidget(self)
        self.table_widget.setColumnCount(6)
        self.table_widget.setHorizontalHeaderLabels(['文件名', '文件类型', '文件大小', '创建时间', '修改时间', '操作'])
        self.table_widget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        main_layout.addWidget(self.table_widget)
        self.table_widget.setItemDelegate(ColorDelegate())

    def on_resize(self, event):
        self.button_back.setFixedWidth(int(self.width() * 0.2))
        self.table_widget.setGeometry(0, 0, self.width(),
                                      self.height() - self.button_select_folder.height() - self.button_back.height())
        super().resizeEvent(event)

    def select_folder(self):
        folder_path = QFileDialog.getExistingDirectory(self, '选择文件夹')
        if folder_path:
            self.current_folder = folder_path
            self.folder_stack = [folder_path]
            self.button_back.setEnabled(True)
            self.load_files(folder_path)

    def load_files(self, folder_path):
        files = os.listdir(folder_path)
        self.table_widget.setRowCount(len(files))

        for row, file_name in enumerate(files):
            file_path = os.path.join(folder_path, file_name)
            file_stat = os.stat(file_path)

            if os.path.isdir(file_path):
                file_type = '文件夹'
            else:
                mime_type, _ = mimetypes.guess_type(file_path)
                if mime_type:
                    file_type = mime_type
                else:
                    file_type = '未知类型'

            file_size = self.format_size(file_stat.st_size)
            creation_time = datetime.fromtimestamp(file_stat.st_ctime).strftime('%Y-%m-%d %H:%M:%S')
            modification_time = datetime.fromtimestamp(file_stat.st_mtime).strftime('%Y-%m-%d %H:%M:%S')

            self.table_widget.setItem(row, 0, QTableWidgetItem(file_name))
            self.table_widget.setItem(row, 1, QTableWidgetItem(file_type))
            self.table_widget.setItem(row, 2, QTableWidgetItem(file_size))
            self.table_widget.setItem(row, 3, QTableWidgetItem(creation_time))
            self.table_widget.setItem(row, 4, QTableWidgetItem(modification_time))

            if os.path.isdir(file_path):
                enter_button = QPushButton('进入文件夹')
                enter_button.setStyleSheet('background-color: #4CAF50; color: white;')
                enter_button.clicked.connect(lambda _, path=file_path: self.enter_folder(path))
                self.table_widget.setCellWidget(row, 5, enter_button)
            else:
                open_button = QPushButton('打开/预览')
                open_button.setStyleSheet('background-color: #008CBA; color: white;')
                open_button.clicked.connect(lambda _, path=file_path: self.open_file(path))
                self.table_widget.setCellWidget(row, 5, open_button)

    def format_size(self, size):
        for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
            if size < 1024.0:
                return f"{size:.2f} {unit}"
            size /= 1024.0
        return f"{size:.2f} PB"
    def enter_folder(self, folder_path):
        self.folder_stack.append(folder_path)
        self.current_folder = folder_path
        self.load_files(folder_path)
        self.button_back.setEnabled(True)

    def go_back(self):
        if len(self.folder_stack) > 1:
            self.folder_stack.pop()
            self.current_folder = self.folder_stack[-1]
            self.load_files(self.current_folder)
            self.button_back.setEnabled(len(self.folder_stack) > 1)

    def open_file(self, file_path):
        if file_path.endswith(('.png', '.jpg', '.jpeg', '.gif')):
            self.open_image(file_path)
        elif file_path.endswith(('.mp4', '.avi', '.mkv')):
            self.open_video(file_path)
        elif file_path.endswith(('.txt', '.log', '.md', '.go', '.py')):
            self.open_text(file_path)
        else:
            QMessageBox.warning(self, '不支持的文件类型', f'不支持打开文件: {file_path}')

    def open_image(self, image_path):
        dialog = QDialog(self)
        dialog.setWindowTitle('图片预览')
        dialog.setGeometry(100, 100, 800, 600)

        image_label = QLabel(dialog)
        pixmap = QPixmap(image_path)
        image_label.setPixmap(pixmap.scaled(800, 600, Qt.KeepAspectRatio))

        layout = QVBoxLayout()
        layout.addWidget(image_label)
        dialog.setLayout(layout)

        dialog.exec_()

    def open_video(self, video_path):
        import subprocess
        import platform

        if platform.system() == "Windows":
            os.startfile(video_path)
        elif platform.system() == "Darwin":  # macOS
            subprocess.call(('open', video_path))
        else:  # linux variants
            subprocess.call(('xdg-open', video_path))

    def open_text(self, text_path):
        with open(text_path, 'r', encoding='utf-8') as file:
            content = file.read()

        dialog = QDialog(self)
        dialog.setWindowTitle('文本预览')
        dialog.setGeometry(100, 100, 800, 600)

        text_edit = QTextEdit(dialog)
        text_edit.setPlainText(content)
        text_edit.setReadOnly(True)

        layout = QVBoxLayout()
        layout.addWidget(text_edit)
        dialog.setLayout(layout)

        dialog.exec_()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
    viewer = FileViewer()
    viewer.show()
    sys.exit(app.exec_())
